<?php
/**
 * zTree class file.
 *
 * ztree Js扩展包
 * @author duanzhiyong <duanzhiyong@hayzone.com>
 * @link http://user.qzone.qq.com/1766921354
 */
Yii::import('zii.widgets.jui.CJuiWidget');
/**
 *
 */
class zTree extends CJuiWidget
{
	/**
	 * 脚本文件列表
	 * 
	 * @var array|string
	 */
	public $scriptFile=array('jquery.ztree.all-3.2.min.js');

	/**
	 * 样式文件列表
	 * 
	 * @var array|string
	 */
	public $cssFile=array('zTreeStyle.css');
	/**
	 * 数据
	 * 
	 * @var array|string
	 */
	public $data='{}';
	/**
	 * 容器宽度
	 * 
	 * @var int
	 */
	public $width;
	/**
	 * 容器高度
	 * 
	 * @var int
	 */
	public $height;
	/**
	 * 是否只允许选择子项
	 * 
	 * @var bool
	 */
	public $onlySon=true;
	/**
	 * 背景容器的ID名
	 * 
	 * @var string
	 */
	public $backgroundId;
	/**
	 * 背景容器
	 * 默认为DIV，为空则没有背景层
	 * @var string
	 */
	public $backgroundTagName='div';
	/**
	 * 背景容器HTML选项
	 * 
	 * @var array
	 */
	public $backgroundHtmlOptions=array();
	/**
	 * assets目录地址
	 * 
	 * @var string
	 */
	public $baseUrl;
	/**
	 * zTree数据的model名称
	 * 设置此项，则为$model::model()->findAll($this->criteria)
	 * @var string|object
	 */
	public $model;
	/**
	 * 查询条件
	 * 设置model属性后生效
	 * @var mixed
	 */
	public $criteria;
	
	/**
	 * 模型名称
	 */
	public $modelName;
	
	/**
	 * 树形节点列名键名
	 * 默认为name
	 * @var string
	 */
	public $treeNodeNameKey='title';
	/**
	 * 树形节点ID键名
	 * 
	 * @var string
	 */
	public $treeNodeKey = 'id';
	/**
	 * 树形节点父ID键名
	 * 
	 * @var string
	 */
	public $treeNodeParentKey = 'parent_id';
	/**
	 * 是否为普通数据
	 * 
	 * @var bool
	 */
	public $setting=array();
	
	/**
	 * 修改 操作的提交url
	 */
	public $editUrl;
	
	/**
	 * 删除 操作的提交url
	 */
	public $delUrl;
	/**
	 * 初始化
	 * @see CJuiWidget::init()
	 */
	public function init()
	{
        $path=dirname(__FILE__).DIRECTORY_SEPARATOR.'assets';
        $this->baseUrl=Yii::app()->getAssetManager()->publish($path);
        $this->themeUrl	= $this->scriptUrl	= $this->baseUrl;
        parent::init();
        
		$this->htmlOptions['id']=$this->id;
		if(isset($this->htmlOptions['class'])) {
			$this->htmlOptions['class']	.= ' ztree';	
		} else {
			$this->htmlOptions['class']	= 'ztree';
		}
		
		if(!empty($this->model)){
			$this->modelName = is_object($this->model) ? get_class($this->model) : $this->model;
		}
		if ($this->width !== null)
		{
			$this->backgroundHtmlOptions['style'] .= " width:{$this->width}px;";
		}
		if ($this->height !== null)
		{
			$this->backgroundHtmlOptions['style'] .= " height:{$this->height}px;";
		}
		if ($this->backgroundId['id'] === null)
		{
			$this->backgroundId	= isset($this->backgroundHtmlOptions['id']) ? $this->backgroundHtmlOptions['id'] :  $this->id.'background';
		}
		$this->backgroundHtmlOptions['id']	= $this->backgroundId;
	}
	
	public function run()
	{
		//外部容器
		if (!empty($this->backgroundTagName))
		{
			echo CHtml::openTag($this->backgroundTagName, $this->backgroundHtmlOptions);
		}
		//树形容器
		echo CHtml::tag('ul', $this->htmlOptions);
		if (!empty($this->backgroundTagName))
		{
			echo CHtml::closeTag($this->backgroundTagName);
		}
		
		// 是否只允许选择子节点
		if ($this->onlySon)
		{
			$this->setting['callback']['beforeClick']= "js:function(treeId, treeNode) {
				var check = (treeNode && !treeNode.isParent);
				return check;
			}";
		}
		if(empty($this->setting['callback']['beforeEditName'])){
			$this->setting['callback']['beforeEditName']= 'js:function(treeId, treeNode) {
				var zTree = $.fn.zTree.getZTreeObj("'.$this->id.'");
				zTree.selectNode(treeNode);
				return confirm("进入 -- " + treeNode.name + " 的编辑状态吗？");
			}';
		}
		if(empty($this->setting['callback']['beforeRemove'])){
			$this->setting['callback']['beforeRemove']= 'js:function(treeId, treeNode) {
				if(treeNode.pId == null){
					alert(treeNode.name + " -- 为基础分类，不可删除！");
					return false;
				}
				var zTree = $.fn.zTree.getZTreeObj("'.$this->id.'");
				zTree.selectNode(treeNode);
				return confirm("确认删除  -- " + treeNode.name + " 吗？");
			}';
		}
		if(empty($this->setting['callback']['beforeRename'])){
			$this->setting['callback']['beforeRename']= 'js:function(treeId, treeNode, newName) {
				if (newName.length == 0) {
					alert("名称不能为空.");
					var zTree = $.fn.zTree.getZTreeObj("'.$this->id.'");
					setTimeout(function(){zTree.editName(treeNode)}, 10);
					return false;
				}
				return true;
			}';
		}
		
		if(empty($this->setting['view']['selectedMulti'])){
			$this->setting['view']['selectedMulti'] = true;
		}
		if(!empty($this->modelName)){
			if(empty($this->setting['callback']['onRemove'])){
				$this->setting['callback']['onRemove']= 'js:function(e, treeId, treeNode) {
					var url = "'.$this->delUrl.'?'.$this->treeNodeKey.'=" + treeNode.id;
					$.post(url,{'.$this->modelName.':{'.$this->treeNodeKey.':treeNode.id}});
				}';
			}
			if(empty($this->setting['callback']['onRename'])){
				$this->setting['callback']['onRename']= 'js:function(e, treeId, treeNode) {
					var url = "'.$this->editUrl.'?'.$this->treeNodeKey.'=" + treeNode.id;
					$.post(url,{'.$this->modelName.':{'.$this->treeNodeNameKey.':treeNode.name,'.$this->treeNodeParentKey.':treeNode.pId}});
				}';
			}
			if(empty($this->setting['callback']['beforeDrag'])){
				$this->setting['callback']['beforeDrag']= 'js:function(treeId, treeNodes) {
					for (var i=0,l=treeNodes.length; i<l; i++) {
						if (treeNodes[i].drag === false) {
							return false;
						}
					}
					return true;
				}';
			}
			if(empty($this->setting['callback']['beforeDrop'])){
				$this->setting['callback']['beforeDrop']= 'js:function(treeId, treeNodes, targetNode, moveType) {
					if(moveType == "inner"){
						return targetNode ? (targetNode.drop !== false) : false;
					}else{
						return targetNode ? (targetNode.drop !== false && targetNode.pId !== null) : false;
					}
				}';
			}
			if(empty($this->setting['callback']['onDrop'])){
				$this->setting['callback']['onDrop']= 'js:function(e, treeId, treeNodes, targetNode, moveType, isCopy) {
					for (var i=0,l=treeNodes.length; i<l; i++) {
						if (treeNodes[i].drag === false) {
							return false;
						}else{
							var url = "'.$this->editUrl.'?'.$this->treeNodeKey.'=" + treeNodes[i].id;
							if(moveType == "inner"){
								var pid = targetNode.id;
							}else{
								var pid = targetNode.pId;
							}
							$.post(url,{'.$this->modelName.':{'.$this->treeNodeNameKey.':treeNodes[i].name,'.$this->treeNodeParentKey.':pid}});
						}
					}
				}';
			}
			if(empty($this->setting['view']['addHoverDom'])){
				$this->setting['view']['addHoverDom']= 'js:function(treeId, treeNode) {
					var sObj = $("#" + treeNode.tId + "_span");
					if (treeNode.editNameFlag || $("#addBtn_"+treeNode.id).length>0) return;
					var addStr = "<span class=\'button add\' id=\'addBtn_" + treeNode.id
						+ "\'title=\'添加\' onfocus=\'this.blur();\'></span>";
					sObj.append(addStr);
					var btn = $("#addBtn_"+treeNode.id);
					if (btn) btn.bind("click", function(){
						var zTree = $.fn.zTree.getZTreeObj("'.$this->id.'");
						var url = "'.$this->editUrl.'";
						var newId = 0;
						$.post(url,{'.$this->modelName.':{'.$this->treeNodeNameKey.':"新名称" + (newCount++),'.$this->treeNodeParentKey.':treeNode.id}},function(result){
							result = eval("("+result+")");
							zTree.addNodes(treeNode, {id:result.'.$this->treeNodeKey.', pId:treeNode.id, name:"新名称" + (newCount++)});
						});
						return false;
					});
				}';
			}
			if(empty($this->setting['view']['removeHoverDom'])){
				$this->setting['view']['removeHoverDom']= 'js:function(treeId, treeNode) {	
					$("#addBtn_"+treeNode.id).unbind().remove();
				}';
			}
		}
		//注册JS
		$cs = Yii::app()->getClientScript();
		$cs->registerCoreScript('jquery');
		Yii::app()->getClientScript()->registerScript(__CLASS__.'#'.$this->id, implode("\n", $this->getRegisterScripts()));
	}
	
	/**
	 * 注册JS列表
	 * 
	 */
	protected function getRegisterScripts()
	{
		$js		= array();
		$data	= $this->getData();
		$setting=CJavaScript::encode($this->setting);
		$js[] = "zTree_{$this->id} = jQuery('#{$this->id}').zTree.init($('#{$this->id}'),{$setting}, {$data});";
		$js[] = "var newCount = 1;"; 
		return $js;
	}
	
	
	/**
	 * 获得数据
	 * 
	 */
	protected function getData()
	{
		if ($this->model !== null)
		{
			$model	= is_object($this->model) ? $this->model : new $this->model;
			if ($model instanceof CModel)
			{
				$data	= $model->findAll($this->criteria);
			}
		}
		else 
		{
			$data	= $this->data;
		}
		
		if(is_array($data))
		{
			if (current($data) instanceof CModel)
			{
				$arr = array();
				foreach ($data as $key => $value)
				{
					$arr[$key]	= $value->getAttributes();
					$arr[$key]['name']	= $arr[$key][$this->treeNodeNameKey];
					$arr[$key]['pId'] =  $arr[$key][$this->treeNodeParentKey];
					$arr[$key]['id'] =  $arr[$key][$this->treeNodeKey];
					$arr[$key]['open'] = ($arr[$key][$this->treeNodeParentKey] == 0) ? true : false;
					$arr[$key]['drag'] = empty($arr[$key]['drag']) ? true : $arr[$key]['drag'];
					$arr[$key]['drop'] = empty($arr[$key]['drop']) ? true : $arr[$key]['drop'];
				}
				$data	= $arr;
			}
			$data	= CJavaScript::encode($data);
		}
		return $data;
	}
}